package com.yzmoney.common.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;


/**
 * Http Client 连接工具
 */
public class HttpClientUtil {

    private static Log log = LogFactory.getLog(HttpClientUtil.class);

    //客户端
    private CloseableHttpClient client;
    //请求
    private HttpRequestBase request;
    //响应
    private CloseableHttpResponse response;
    //参数
    private Map<String, String> paramMap;
    //编码
    private String encode;
    //URL
    private String url;

    protected HttpClientUtil() {
        //client = HttpClients.createDefault();
        encode = "UTF-8";
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void setParamMap(Map<String, String> paramMap) {
        this.paramMap = paramMap;
    }

    public void setEncode(String encode) {
        this.encode = encode;
    }

    public static String get(String url, Map<String, String> paramMap, String encode) {

        HttpClientUtil util = new HttpClientUtil();
        util.setUrl(url);

        if (encode != null && !encode.isEmpty())
            util.setEncode(encode);
        util.setParamMap(paramMap);

        return util.get();
    }


    /**
     * 发起一个Http Get 请求
     */
    public String get() {
        client = HttpClients.createDefault();
        // 创建参数队列
        String param = parseParamForGet();
        // 创建httppost
        log.debug("prepare executing request :" + url + "?" + param);

        if (org.apache.commons.lang3.StringUtils.isEmpty(param)) {
            request = new HttpGet(url);
        } else {
            request = new HttpGet(url + "?" + param);
        }


        try {
            response = client.execute(request);
        } catch (IOException e) {
            e.printStackTrace();
        }

        HttpEntity entity = response.getEntity();

        Header encodeHeader = entity.getContentEncoding();
        String responseEncode;
        if (encodeHeader == null) {
            log.debug("No Content Encoding Get!");
            log.debug("System will use default encode.");
            responseEncode = encode;
        } else
            responseEncode = encodeHeader.getValue();
        try {
            return EntityUtils.toString(entity, responseEncode);
        } catch (ParseException e) {
            log.warn(JDKStackTrace.getJDKStrack(e));
        } catch (IOException e) {
            log.warn(JDKStackTrace.getJDKStrack(e));
        }

        finishRequest();

        return null;
    }

    /**
     * 结束请求
     */
    private void finishRequest() {
        try {
            response.close();
            client.close();
            log.debug("Http Client successful close.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String post(String url, Map<String, String> paramMap, String encode) {

        HttpClientUtil util = new HttpClientUtil();
        util.setUrl(url);

        if (encode != null && !encode.isEmpty())
            util.setEncode(encode);
        util.setParamMap(paramMap);

        return util.post();
    }

    public static String post(String url, String jsonParam, String encode) {
        HttpClientUtil util = new HttpClientUtil();
        util.setUrl(url);
        if (encode != null && !encode.isEmpty())
            util.setEncode(encode);
        return util.post(jsonParam);
    }

    public String post(String jsonParam) {
        // 创建默认的httpClient实例.
        client = HttpClients.createDefault();
        // 创建httppost
        request = new HttpPost(url);

        try {

            log.debug("executing request :" + request.getURI());

            ((HttpPost) request).setEntity(new StringEntity(jsonParam, "utf-8"));

            response = client.execute(request);
            try {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    log.debug("Post success,Response received.");
                    Header encodeHeader = entity.getContentEncoding();
                    String responseEncode;
                    if (encodeHeader == null) {
                        log.debug("No Content Encoding Get!");
                        log.debug("System will use default UTF-8 encode.");
                        responseEncode = "UTF-8";
                    } else
                        responseEncode = encodeHeader.getValue();
                    return EntityUtils.toString(entity, responseEncode);
                }
            } finally {
                response.close();
            }
        } catch (ClientProtocolException e) {
            log.warn(JDKStackTrace.getJDKStrack(e) + ",url=" + url);
        } catch (UnsupportedEncodingException e) {
            log.warn(JDKStackTrace.getJDKStrack(e) + ",url=" + url);
        } catch (IOException e) {
            log.warn(JDKStackTrace.getJDKStrack(e) + ",url=" + url);
        } finally {
            // 关闭连接,释放资源
            try {
                client.close();
            } catch (IOException e) {
                log.warn(JDKStackTrace.getJDKStrack(e) + ",url=" + url);
            }
        }

        return null;
    }


    public String post() {
        // 创建默认的httpClient实例.
        client = HttpClients.createDefault();
        // 创建httppost
        request = new HttpPost(url);
        // 创建参数队列
        List<NameValuePair> formparams = parseParamForPost();

        try {
            UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(formparams, encode);

            log.debug("executing request :" + request.getURI());

            ((HttpPost) request).setEntity(uefEntity);

            response = client.execute(request);
            try {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    log.debug("Post success,Response received.");
                    Header encodeHeader = entity.getContentEncoding();
                    String responseEncode;
                    if (encodeHeader == null) {
                        log.debug("No Content Encoding Get!");
                        log.debug("System will use default UTF-8 encode.");
                        responseEncode = "UTF-8";
                    } else
                        responseEncode = encodeHeader.getValue();
                    return EntityUtils.toString(entity, responseEncode);
                }
            } finally {
                response.close();
            }
        } catch (ClientProtocolException e) {
            log.warn(JDKStackTrace.getJDKStrack(e));
        } catch (UnsupportedEncodingException e) {
            log.warn(JDKStackTrace.getJDKStrack(e));
        } catch (IOException e) {
            log.warn(JDKStackTrace.getJDKStrack(e));
        } finally {
            // 关闭连接,释放资源
            try {
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    private HttpEntity getResult() {
        return response.getEntity();
    }

    /**
     * 得到字节数组
     */
    private byte[] getByteResult(HttpEntity entity) {
        try {
            return EntityUtils.toByteArray(entity);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 得到字符串
     */
    private String getStringResult(HttpEntity entity, String encode) {
        try {
            return EntityUtils.toString(entity, encode);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据Map得到参数
     */
    private List<NameValuePair> parseParamForPost() {

        List<NameValuePair> paramList = new ArrayList<NameValuePair>();

        if (paramMap == null)
            return paramList;

        for (String key : paramMap.keySet()) {
            paramList.add(new BasicNameValuePair(key, paramMap.get(key)));
        }

        return paramList;
    }

    /**
     * 转化为Get用参数
     */
    private String parseParamForGet() {
        StringBuffer buf = new StringBuffer();
        if (paramMap == null)
            return buf.toString();
        for (String key : paramMap.keySet()) {
            try {
                buf.append(key).append("=").append(URLEncoder.encode(paramMap.get(key), encode)).append("&");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        if (buf.length() > 0) {
            buf.deleteCharAt(buf.length() - 1);
        }
        return buf.toString();
    }
}
